/*
 *  Copyright (C) 2011 JiangHongTiao <jjurco.sk_gmail.com>
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 * 
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package sk.lieskove301.jianghongtiao.liaad.prisoner.payoff;

import java.util.ArrayDeque;
import java.util.Deque;
import sk.lieskove301.jianghongtiao.liaad.prisoner.strategy.FightResultEnum;

/**
 * @param pi cartel profit
 * @param ro probability of detection
 * @param f size of fine
 * @author xjuraj
 */
public class PayoffCartel implements PayoffValue {
    private double pi;
    private double ro;
    private double f;
    private final Deque<Double> bC;
    private final Deque<Double> CB;
    private final Deque<Double> BC;
    private final Deque<Double> bB;

    /**
     *
     * @param pi cartel profit
     * @param ro probability of detection
     * @param f size of fine
     */
    public PayoffCartel(double pi, double ro, double f) {
        this.pi = pi;
        this.ro = ro;
        this.f = f;
        bC = bothCooperate();
        CB = cooperateBetray();
        BC = betrayCooperate();
        bB = bothBetray();
    }

    public Deque<Double> countPayoffValues(FightResultEnum result) {
        if(result == FightResultEnum.BothCooperate)   return bC;
        if(result == FightResultEnum.CooperateBetray) return CB;
        if(result == FightResultEnum.BetrayCooperate) return BC;
        if(result == FightResultEnum.BothBetray)      return bB;
        throw new IllegalStateException("Shit happened!");
    }

    private Deque<Double> cooperateBetray(){
        Deque<Double> values = new ArrayDeque<Double>(2);
        values.addFirst(new Double(-1*f));
        values.addLast(new Double(0));
        return values;
    }

    private Deque<Double> betrayCooperate(){
        Deque<Double> values = new ArrayDeque<Double>(2);
        values.addFirst(new Double(0));
        values.addLast(new Double(-1*f));
        return values;
    }

    private Deque<Double> bothCooperate(){
        Deque<Double> values = new ArrayDeque<Double>(2);
        Double val = ((1-ro)*pi)-(ro*f);
        values.addFirst(val);
        values.addLast(val);
        return values;
    }

    private Deque<Double> bothBetray(){
        Deque<Double> values = new ArrayDeque<Double>(2);
        Double val = -0.5*f;
        values.addFirst(val);
        values.addLast(val);
        return values;
    }
}
